﻿using System;
using System.Runtime.InteropServices;
using Irrlicht.Net.Core;

namespace Irrlicht.Net.Scene
{
    public class CameraSceneNode : SceneNode
    {
        #region PInvoke
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void CameraSN_BindTargetAndRotation(IntPtr camera, bool bound);

        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern float CameraSN_GetAspectRatio(IntPtr camera);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern float CameraSN_GetFarValue(IntPtr camera);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern float CameraSN_GetFOV(IntPtr camera);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern float CameraSN_GetNearValue(IntPtr camera);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern float CameraSN_GetTarget(IntPtr camera, ref float x, ref float y, ref float z);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern bool CameraSN_GetTargetAndRotationBinding(IntPtr camera);

        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern bool CameraSN_IsInputRecieverEnabled(IntPtr camera);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern bool CameraSN_IsOrthogonal(IntPtr camera);

        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void CameraSN_SetAspectRatio(IntPtr camera, float aspect);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void CameraSN_SetFarValue(IntPtr camera, float far);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void CameraSN_SetFOV(IntPtr camera, float fov);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void CameraSN_SetInputRecieverEnabled(IntPtr camera, bool enabled);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void CameraSN_SetNearValue(IntPtr camera, float near);

        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void CameraSN_SetTarget(IntPtr camera, float x, float y, float z);
        [DllImport("IrrlichtW.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern void CameraSN_SetUpVector(IntPtr camera, float x, float y, float z);
        #endregion

        public CameraSceneNode(IntPtr pointer)
            : base(pointer)
        {
        }

        public bool IsBoundTargetAndRotation
        {
            get
            {
                return CameraSN_GetTargetAndRotationBinding(pointer);
            }
            set
            {
                CameraSN_BindTargetAndRotation(pointer, value);
            }
        }
        public bool IsInputRecieverEnabled
        {
            get
            {
                return CameraSN_IsInputRecieverEnabled(pointer);
            }
        }
        public bool IsOrthogonal
        {
            get
            {
                return CameraSN_IsOrthogonal(pointer);
            }
        }

        public float AspectRatio
        {
            get
            {
                return CameraSN_GetAspectRatio(pointer);
            }
            set
            {
                CameraSN_SetAspectRatio(pointer, value);
            }
        }
        public float FarValue
        {
            get
            {
                return CameraSN_GetFarValue(pointer);
            }
            set
            {
                CameraSN_SetFarValue(pointer, value);
            }
        }
        public float FOV
        {
            get
            {
                return CameraSN_GetFOV(pointer);
            }
            set
            {
                CameraSN_SetFOV(pointer, value);
            }
        }
        public float NearValue
        {
            get
            {
                return CameraSN_GetNearValue(pointer);
            }
            set
            {
                CameraSN_SetNearValue(pointer, value);
            }
        }

        public Vector3D Target
        {
            get
            {
                float x = 0, y = 0, z = 0;
                CameraSN_GetTarget(pointer, ref x, ref y, ref z);
                return new Vector3D(x, y, z);
            }
            set
            {
                Vector3D target = value;
                CameraSN_SetTarget(pointer, target.x, target.y, target.z);
            }
        }
        public Vector3D Up
        {
            get
            {
                float x = 0, y = 0, z = 0;
                CameraSN_GetTarget(pointer, ref x, ref y, ref z);
                return new Vector3D(x, y, z);
            }
            set
            {
                Vector3D up = value;
                CameraSN_SetUpVector(pointer, up.x, up.y, up.z);
            }
        }
    }
}
